==Объекты и их обработчики==

актуально для версии движка micro.fb v.VM.1.0

В общем виде вызова процедур и функций вместо конкретных значений показаны переменные $args[] и args[]. Это не действительные переменные, а лишь удобная замена значений аргументов. $args - заменяет аргумент с текстовым значением, args - с числовым. В квадратных скобках указывается номер аргумента. Номера аргументов считаются с нуля. $args[0] - нулевой аргумент, $args[1] - первый аргумент и т.д. В приведённых конкретных кусочках кода переменные $args и args являются действительными.

=Представление объектов=

Каждый объект являет собой набор значений в специальных массивах. Специальные массивы, предназначенные для хранения информации об объектах, в дальнейшем будут называться таблицей данных, или таблицей объектов.

Можно представить таблицу объектов как абстрактную таблицу, где столбцы определяются по именам массивов, а строки по индексу элементов:

row\col |  $id_array  |  $object_array  |  $position_array  |  kolvo_array  |  charge_array  |  $run_array  
--------|-------------|-----------------|-------------------|---------------|----------------|--------------
	0   | $id_array[0]| $object_array[0]| $position_array[0]| kolvo_array[0]| charge_array[0]| $run_array[0]
	1   | $id_array[1]| $object_array[1]| $position_array[1]| kolvo_array[1]| charge_array[1]| $run_array[1]
	2   | $id_array[2]| $object_array[2]| $position_array[2]| kolvo_array[2]| charge_array[2]| $run_array[2]
	... |.............|.................|...................|...............|................|..............
	N   | $id_array[N]| $object_array[N]| $position_array[N]| kolvo_array[N]| charge_array[N]| $run_array[N]

Таким образом каждый объект является набором значений в группе массивов, причём каждое определённое значение занимает один элемент определённого массива, но номера элементов всех массивов (для одного объекта) одинаковы. Вот значения массивов:

	$id_array	-	массив хранит уникальные идентификаторы объектов. Каждый объект должен обладать уникальным идентификатором, чтобы отличаться от других, подобных ему, объектов.
	$object_array	-	массив хранит тела (описания) объектов. Тело любого объекта может содержать идентификаторы класса, типа, подтипа, вида и т.п., а так же любую другую информацию, в полной или краткой форме описывающую объект.
	$position_array	-	массив хранит идентификаторы родительских объектов. Любой объект игры может быть "помещён" в другой объект. Для подробностей смотри раздел "Наследование".
	kolvo_array	-	массив предназначен для хранения количества. Например для хранения нескольких одинаковых предметов может использоваться один объект, но со значением в массиве kolvo_array отличным от нуля.
	charge_array-	массив предназначен для хранения "заряда" объекта. Изначально был введён для сопровождения значения заряда магических посохов в игре "Магикон", однако в последствии стал так же применяться как вспомогательный массив для подсчёта характеристики предмета, которую нельзя описать как количество.
	$run_array	-	в этот массив помещается в виде текстового значения исполняемый код, который вызывается и выполняется в разных участках игры. Подробнее о динамическом коде, сопровождающем объекты, читай в разделе "Динамический код в $run_array".

Примеры готовых объектов:
	
	$id_array[30]='КУСТХ_010101'
	$object_array[30]='<ratch> [:куст_хищник:] [name:Куст-Хищник|Куста-Хищника|Кусту-Хищнику|Куст-Хищник|Кустом-Хищником|Кусте-Хищнике:name] [np::np] [power:10] [fast:9] [sex:male:sex]'
	$position_array[30]='page.3'
	kolvo_array[30]=1
	charge_array[30]=0
	$run_array[30]=''

	$id_array[27]='НЧВДН_000004'
	$object_array[27]='<obj> [:ночное_видение:] [name:Инфракрасные очки «Ночное зрение»|Инфракрасных очков «Ночное зрение»|Инфракрасным очкам «Ночное зрение»|Инфракрасные очки «Ночное зрение»|Инфракрасными очками «Ночное зрение»|Инфракрасных очках «Ночное зрение»:name] [np:[доспех] [очки] [инфракрасное зрение]:np] [text:Они позволяют видеть в темноте.:text][hide.onloc][pos:место_в_рюкзаке:pos]'
	$position_array[27]='page.0'
	kolvo_array[27]=1
	charge_array[27]=0
	$run_array[27]='![page0.dErT]
if $args[0]='!addobj.pos!' and $curloc='page.0':
$GAME_VALUE['interface']='[game]'
	! ищем идентификатор сумки с предметом, содержащим текущий код.
	$args['id']=$func('prv.bag','!'+'\['+'page0\.'+'dErT\]','regrun')
	! подменяем позицию
	if $args['id']!'':
		$result=$args['id']
		exit
	end
end
if $args[0]='!putobj.prv!' and $curloc!'page.0':
! если предмет сбрасывается на другой локации, нужно избавиться от динамического кода и метки [hide.onloc]
	args['pit']=arrpos('$id_array',$args[1])
	$object_array[args['pit']]=$replace($object_array[args['pit']],'[hide.onloc]')
	$args['run']=$strfind($run_array[args['pit']],'!'+'\['+'page0\.'+'dErT\]'+'[\s\S]*'+'!'+'\[\/'+'page0\.'+'dErT\]')
	$run_array[args['pit']]=$replace($run_array[args['pit']],$args['run'])
end
![/page0.dErT]'

	$id_array[20]='БЛСТР_000003'
	$object_array[20]='<obj> [:бластер:]  [np:[оружие] [огнестрельное] [пистолет]:np] [name:Бластер:name] [maxchrg:] [quest] [text:Вы можете в любой момент убить любого из противников смертоносным лучом. Сделать это можно даже в разгаре боя. Но по причинам, объясненным в Предисловии, число зарядов невелико, их приходится беречь.:text]'
	$position_array[20]='ПОЯС-КОБУРА'
	kolvo_array[20]=1
	charge_array[20]=1
	$run_array[20]=''

	$id_array[3]='ЗАПЯСТЬЕ'
	$object_array[3]='<body> [:запястье:]'
	$position_array[3]='INVENTORY'
	kolvo_array[3]=1
	charge_array[3]=0
	$run_array[3]=''

=Создание объектов=

Все объекты создаются процедурой crt.obj. Для движка micro.fb характерно присутствие всех видов и подвидов объектов, как отдельных видов объектов, в специальных базах. Объекты делятся по классам. Классы указываются в теле объектов с помощью идентификаторов классов (далее классы будут обозначаться через идентификаторы классов):
	<obj> - предметы
	<body> - части тела/места в рюкзаке
	<ratch> - противники
	<knew> - знания/записи

При создании объекта необходимо указывать класс. Если класс не указан, предполагается, что создаётся объект класса <obj>.

Процедура crt.obj вызывается так:

gosub 'crt.obj',$args[0],$args[1],$args[2],args[3],args[4],$args[5],$args[6]

, где
	$args[0]	-	идентификатор вида объекта, короткое слово. Если короткое слово не указано, объект генерируется на основе информации, переданной в $args[2]. Если короткое слово указано, происходит обращение к базе объектов в зависимости от класса объекта (<obj>, <ratch> и т.д.)
	$args[1]	-	предпочтительный уникальный идентификатор объекта. Можно не указывать, тогда идентификатор будет сгенерирован случайным образом. Уникальный идентификатор помещается в массив $id_array.
	$args[2]	-	дополнительное к телу предмета. Здесь же должен указываться идентификатор класса. Если передано пустое значение, будет создан объект класса <obj>. Если указать в этом аргументе какую либо дополнительную информацию, описывающую объект, она будет добавлена в тело объекта, без замены исходной информации. 
	args[3]		-	заряд объекта, или сопровождающее объект число, которое нельзя описать как количество. Значение помещается в массив charge_array.
	args[4]		-	количество. Значение помещается в массив kolvo_array.По умолчанию количество любого объекта равно 1 штуке.
	$args[5]	-	идентификатор местоположения. Если не указан, объект помещается на текущей локации. Значение прописывается в массив $position_array.
	$args[6]	-	сопроводительный динамический код объекта. Значение помещается в массив $run_array.

Можно обратиться к crt.obj как к функции. Результатом функции будет идентификатор созданного объекта.

Примеры создания объектов, описанных в предыдущем разделе:

	gosub 'crt.obj','','ЗАПЯСТЬЕ','<body> [:запястье:]',0,1,'INVENTORY'

	gosub 'crt.obj','','БЛСТР_000003','<obj> [:бластер:]  [np:[оружие] [огнестрельное] [пистолет]:np] [name:Бластер:name] [maxchrg:] [quest] [text:Вы можете в любой момент убить любого из противников смертоносным лучом. Сделать это можно даже в разгаре боя. Но по причинам, объясненным в Предисловии, число зарядов невелико, их приходится беречь.:text]',1,1,'ПОЯС-КОБУРА'

	$args['динамический код предметов']={![page0.dErT]
	if $args[0]='!addobj.pos!' and $curloc='page.0':
	$GAME_VALUE['interface']='[game]'
		! ищем идентификатор сумки с предметом, содержащим текущий код.
		$args['id']=$func('prv.bag','!'+'\['+'page0\.'+'dErT\]','regrun')
		! подменяем позицию
		if $args['id']!'':
			$result=$args['id']
			exit
		end
	end
	if $args[0]='!putobj.prv!' and $curloc!'page.0':
	! если предмет сбрасывается на другой локации, нужно избавиться от динамического кода и метки [hide.onloc]
		args['pit']=arrpos('$id_array',$args[1])
		$object_array[args['pit']]=$replace($object_array[args['pit']],'[hide.onloc]')
		$args['run']=$strfind($run_array[args['pit']],'!'+'\['+'page0\.'+'dErT\]'+'[\s\S]*'+'!'+'\[\/'+'page0\.'+'dErT\]')
		$run_array[args['pit']]=$replace($run_array[args['pit']],$args['run'])
	end
	![/page0.dErT]
	}
	gosub 'crt.obj','ночное_видение',"НЧВДН_000004",'[hide.onloc]',0,1,'',$args['динамический код предметов']

	gosub 'crt.obj','куст_хищник','КУСТХ_010101','<ratch>'

=Удаление объектов=

Удаление объекта производится удалением ячеек всех массивов, входящих в таблицу объектов. Для этого написана специальная процедура del.obj.id. Собственно вот весь код процедуры:

	args['pos']=arrpos('$id_array',$args[0])
	killvar '$id_array',args['pos']
	killvar '$object_array',args['pos']
	killvar '$position_array',args['pos']
	killvar 'kolvo_array',args['pos']
	killvar 'charge_array',args['pos']
	killvar '$run_array',args['pos']

Как видно из кода, объект удаляется по своему уникальному идентификатору. Таким образом невозможно удалить другой объект, тело которого идентично удаляемому.

Пример вызова процедуры:

gosub 'del.obj.id','КУСТХ_010101'

=Сортировка объектов=

Поскольку все объекты вносятся в таблицу объектов по мере создания, более новые объекты обнаруживаются разными механизмами позже, чем более старые. Иногда нужно поменять несколько объектов местами, чтобы более новый объект обнаруживался раньше старого. Для этого была написана процедура rtp.obj. Она меняет два объекта местами в таблице объектов. Пример вызова процедуры:

gosub 'rtp.obj',$temp_id[0],'ПОЯС-КОШЕЛЬ_02'

=Поиск объектов=

Поиск объектов в micro.fb реализован довольно скудно. Чтобы найти объект в таблице данных, необходимо воспользоваться рядом функций QSP.

Поиск по уникальному идентификатору:

	arrpos('$id_array','идентификатор')

	Этот приём позволяет быстро найти строку объекта в таблице данных. Так, например, можно получить и вывести тело объекта по его уникальному идентификатору:

	*pl $object_array[arrpos('$id_array','идентификатор')]

	Аналогично можно произвести поиск объекта, расположенного в нужном объекте:

	arrpos('$position_array','идентификатор')

Поиск по шаблону тела объекта:

	Если нам нужно найти объект класса <obj> типа [доспех] можно воспользоваться таким способом:

	arrcomp('$object_array','[\s\S]*<obj>[\s\S]*\[доспех\][\s\S]*')

	Аналогично можно производить поиск и по другим массивам.

Поиск дочерних объектов.

	Производится специальной процедурой get.daughter.obj. Эта процедура позволяет найти все объекты, вложенные в другой объект. Т.е. в таблице данных обнаруживаются все объекты, в $position_array[] которых указан текущий идентификатор.

	Вызов процедуры:

	gosub 'get.daughter.obj',$args[0],$args[1],$args[2],$args[3]

	, где
		$args[0]	-	идентификатор объекта, для которого мы ищем дочерние ("вложенные") объекты.
		$args[1]	-	регулярное выражение, по которому будет производиться дополнительная проверка. Проверяется наличие подстроки, соответствующей указанному шаблону, в теле объекта. Например, можно выбрать объекты определённого класса. 
		$args[2]	-	имя массива, в который будут помещаться идентификаторы найденных дочерних объектов. По умолчанию $temp_id.
		$args[3]	-	регулярное выражение, по которому будет производиться дополнительная проверка. Проверяется наличие подстроки, соответствующей указанному шаблону, в динамическом коде объекта. Например, можно найти объекты, динамический код которых должен выполняться по определённому управляющему слову.

	Пример вызова:

	gosub 'get.daughter.obj','INVENTORY','<obj>','$daughter_id'

	Данная команда найдёт все объекты класса <obj>, "вложенные" в объект с идентификатором INVENTORY.

	Можно использовать get.daughter.obj как функцию, тогда результатом будет возвращаться значение true (дочерние объекты найдены) или false (дочерние объекты не найдены).

	Подробнее о понятиях "родительских" и "дочерних" объектов, читай в разделе "Наследование"

=Работа с объектами класса <obj>. Предметы=

--Создание предметов--

Предметы, как и все прочие объекты в игре, создаются процедурой crt.obj. Чтобы создать предмет и сбросить его на текущей локации, достаточно указать лишь один аргумент - идентификатор вида (короткое слово) предмета. Пример:

gosub 'crt.obj','шлем'

Однако, такой способ предполагает, что предмет до этого был описан в специальной локации - базе предметов base.obj.

	-base.obj-

	Локация представляет собой функцию, которая, в зависимости от поступивших к ней команд, возвращает готовое тело предмета.
	Пример вызова:

	$func('base.obj','шлем')

	Данная функция вернёт готовое тело предмета с идентификатором вида "шлем". Общий вызов функции:

	$func('base.obj',$args[0],$args[1])

	, где
		$args[0]	-	идентификатор вида (короткое слово) предмета. Каждый предмет в базе заключён в конструкицю проверки условия. Если $args[0] будет соответствовать нужной строке, в результат добавляется тело предмета. Если в $args[0] передано пустое значение - тело предмета не возвращается.
		$args[1]	-	дополнительная строка к телу предмета. Передаётся в том случае, если нужно расширить тело предмета дополнительными признаками и описаниями.

	Если база предметов создаётся заново, она должна иметь следующую структуру:

		1.	В самом начале локации должны быть эти строки:

			! ------------ base.obj ----- шапка -------------------------------
			$args[0] = $args[0]							&	!	краткое имя предмета/идентификатор вида
			$args[1]=TRIM($replace($args[1],'<obj>'))	&	!	дополнительные параметры предмета
			$args['obj']+="<obj> "						&	!	идентификатор типа
			! ------------ base.obj ----- шапка -------------------------------

		2.	Далее должны идти конструкции проверки условий на соответствие идентификаторам видов. Внутри конструкций пременной $args['obj'] присваивается тело предмета. Вот пример такой конструкции, описывающей предмет "шлем":

			! ------------ base.obj ---- предмет шлем ------- тело ------------
			:шлем
			if $args[0]='шлем':
				$args['obj'] += '[:шлем:] [name:Шлем|Шлема|Шлему|Шлем|Шлемом|Шлеме:name] [np:[доспех] [шлем]:np] [text:Красивый рыцарский шлем. Пожалуй, в таком вас могут принять за настоящего рыцаря.:text]'
			end
			! ------------ base.obj ---- предмет шлем ------- тело ------------

		3.	В конце локации после всех конструкций, описывающих предмет, должны идти вот эти строки:

			! ------------ base.obj ----- низ -------------------------------
			$args['obj']+=$args[1]	&	!	дополнительные параметры
			if instr($args['obj'],'[pos:')=0: $args['obj']+='[pos:место_в_рюкзаке:pos]'
			$result=$args['obj']
			! ------------ base.obj ----- низ -------------------------------

	Рекомендую всё же использовать уже готовую базу, например из игры "Вереница миров" Ольги Голотвиной, автор порта Aleks Versus.

Чтобы создать предмет, не используя базу, следует передать в аргументе $args[2] полное, готовое тело предмета. Однако локацию base.obj написать необходимо, поскольку окончательное тело формируется именно в ней. В пустую локацию base.obj помести вот этот код, и тогда всё будет работать:
	
	! ------------ base.obj ----- шапка -------------------------------
	$args[0] = $args[0]	&	!	краткое имя предмета/идентификатор вида
	$args[1] = $args[1]	&	!	дополнительные параметры предмета
	if instr($args[1],'<obj>')=0: $args['obj']+="<obj> "	&	!	идентификатор класса
	! ------------ base.obj ----- шапка -------------------------------

	! ------------ base.obj ----- низ -------------------------------
	$args['obj']+=$args[1]	&	!	дополнительные параметры
	if instr($args['obj'],'[pos:')=0: $args['obj']+='[pos:место_в_рюкзаке:pos]'
	$result=$args['obj']
	! ------------ base.obj ----- низ -------------------------------

Пример создания предмета без использования базы:

gosub 'crt.obj','','','<obj> [:шлем:] [name:Шлем|Шлема|Шлему|Шлем|Шлемом|Шлеме:name] [np:[доспех] [шлем]:np] [text:Красивый рыцарский шлем. Пожалуй, в таком вас могут принять за настоящего рыцаря.:text]'

Чтобы поместить один предмет в другой предмет, нужно указать в $args[5] идентификатор местоположения. Например, у нас есть предмет "сумка" с идентификатором "сумка.ла4792". Чтобы "поместить" предмет "шлем" в "сумку" при создании предмета "шлем", пишем так:

gosub 'crt.obj','шлем','','<obj>',0,1,'сумка.ла4792'

--Поиск предмета в инвентаре--

Инвентарь - это особый объект игры, создающийся в самом начале. Он принадлежит уникальному классу <INVENTORY> и имеет определённый уникальный идентификатор. Инвентарь помещается в корневой объект ROOF. ROOF - тоже уникальный объект, который является корневым объектом для всех прочих объектов игры. Вот конкретный код для создания этих объектов:

	! корень:
	gosub 'crt.obj','','ROOF','<ROOF>',0,1,''
	! инвентарь:
	gosub 'crt.obj','','INVENTORY','<INVENTORY>',0,1,'ROOF'

В инвентарь помещаются объекты класса <body>. В каждый объект класса <body> можно поместить лишь один объект класса <obj>. Объекты класса <body> далее будут называться "частями тела" или "сумками". Таким образом инвентарь представляет собой набор сумок и частей тела. Все прочие предметы при подъёме размещаются либо в этих сумках, либо в других предметах. В связи с этим были разработаны специальные функции поиска по инвентарю.

	-prv.bag-

	Данная функция проверяет инвентарь на наличие отсутствие предмета. Результатом работы функции является идентификатор сумки, в которой размещён искомый предмет. Общий вид вызова функции:

	$func('prv,bag',$args[0],$args[1],$args[2])

	, где
		$args[0]	-	идентификатор предмета или регулярное выражение. Иными словами значение, по которому производится поиск предмета.
		$args[1]	-	управляющая конструкция. Предназначена для выбора режима поиска:

			id - поиск по уникальному идентификатору объекта.
			regexp - поиск по регулярному выражению в телах объектов. Производится поиск подстроки, соответствующей шаблону, в телах объектов.
			regrun - поиск по регулярному выражению в сопроводительном коде объектов. Производится поиск подстроки, соответствующей шаблону, в сопроводительном коде объектов.

		$args[2]	-	дополнительная проверка на наличие идентификатора вида в объекте класса <body>. Идентификатор вида передаётся в чистом виде, т.е. без тегов "[:" и ":]".

	Пример поиска предмета в инвентаре по идентификатору:

	$func('prv.bag','НЧВДН_000004','id')

	Пример поиска предмета в инвентаре по регулярному выражению:

	$func('prv.bag','\[очки\]','regexp')

	Пример поиска первой пустой сумки требуемого вида в инвентаре:

	$func('prv.bag','','','место_в_рюкзаке')

	-prv.obj.inBag-

	Функция поиска предмета по идентификатору вида и проверки его наличия в инвентаре (можно произвести проверку наличия предмета не только в инвентаре, но и скажем в Знаниях). Результатом работы функции является идентификатор найденного предмета. Общий вид вызова функции:

	$func('prv.obj.inBag',$args[0],$args[1])

	, где
		$args[0]	-	идентификатор вида предмета.
		$args[1]	-	класс родительского объекта (сумки). Если не указан, поиск производится по объектам класса <body>.

	Пример поиска предмета в инвентаре:

	$func('prv.obj.inBag','шлем')

	Пример поиска заметки в "Знаниях":

	$func('prv.obj.inBag','тюрьма','<KNOWLEDGE>')

--Структура предметов--

Тело каждого предмета описывается наборами тегов. Теги - это метки, выделяющие некоторую информацию (если вы знакомы с языком разметки html, вы наверняка представляете, что такое теги). В движке micro.fb используются одиночные и парные теги следующих типов:
	[tag]		-	тег типа, метка типа. Одиночный тег, указывающий на наличие определённого свойства у объекта.
	[tag:00]	-	тег исчисления. Одиночный тег, указывающий на численное выражение какого-либо свойства.
	[tag: и :tag] -	открывающий и закрывающие теги, указывающие на текстовое значение какого-либо свойства.
	<tag>		-	тег класса. Одиночный тег, указывающий на класс объекта.

Вот теги, которые можно использовать при описании предмета (между сдвоенными тегами помещается пример значения:

	[:short_word:]	-	пустые теги. Идентификатор вида.
	[name:Имя|Имени|Имени|Имя|Именем|Имени:name]	-	теги имени. Между ними через вертикальную черту помещаются варианты имени в разных падежах: Именительный|Родительный|Дательный|Винительный|Творительный|Предложный.
	[text:ТЕКСТ:text]	-	текст, который будет выводиться на экран при просмотре информации о предмете.
	[eating:CODE:eating]	-	динамический код, который выполняется при "съедании" предмета. (Пункт меню "Съесть")
	[useon:00]		-	страница, на которую будет произведён переход при использовании предмета. (Пункт меню "Воспользоваться")
	[useoff:AVS_MARK:useoff]	-	условие использования предмета типа [доспех]. (Пункт меню "Надеть")
	[pos:МЕСТО_В_РЮКЗАКЕ:pos]	-	позиция, в которую добавляется предмет при поднятии с локации. В качестве позиции указывается идентификатор вида той части тела, в которую добавляется предмет. 
	[maxchrg:00]	-	максимально возможный заряд предмета.
	[np: :np]		-	набор признаков предмета. Типы, подтипы, прочее.

--Подъём предметов в инвентарь--

Для подъёма предметов в инвентарь была написана специальная процедура add.obj. Процедура эта выполняет простые проверки и в зависимости от результата добавляет или не добавляет предмет в инвентарь. Вот порядок работы функции:

	1.	Вычисляется расположение предмета в таблице данных, набор признаков, идентификатор вида и прочие данные.
	2.	Если в наборе признаков присутствует признак типа [монета], предмет добавляется в "Кошель". Потом производится принудительный переход к концу процедуры (пункт 7). Если признак типа [монета] отсутствует, выполняются следующие пункты.
	3.	При наличии динамического кода в предметах могут быть подменены идентификатор предмета и идентификатор искомого местоположения.
	4.	Если не указан идентификатор места в инвентаре, куда хотим положить предмет, производится поиск первой свободной части тела.
	5.	Проверяем, не присутствует ли в данной позиции другой предмет. Если другой предмет есть, сбрасываем его на локации.
	6.	Кладём поднимаемый с локации предмет в указанное местоположение. Это происходит простым возвращением ячейке массива $position_array идентификатора местоположения (части тела).
	7.	Конец процедуры. Здесь проверяется, не заблокирован ли автоматический переход на текущую локацию. Если переход не заблокирован, он осуществляется.

Общий вид вызова процедуры:

gosub 'add.obj',$args[0],$args[1],$args[2]

, где
	$args[0]	-	идентификатор поднимаемого с локации предмета.
	$args[1]	-	идентификатор части тела, в которую следует поместить предмет.
	$args[2]	-	управляющая конструкция. Список рабочих управляющих конструкций:
			//nope.goto//	-	запрещает автоматический переход на текущую локацию. Поскольку автоматический переход происходит по команде goto, это может прервать выполнение части кода после обращения к процедуре add.obj.

--Сбрасывание предмета на локации--

Для сбрасывания предмета на локации была написана процедура put.obj. Принцип действия её очень прост. В ячейку массива $position_array, соответствующую указанному предмету, прописывается имя текущей локации. Общий вызов процедуры:

gosub 'put.obj',$args[0],$args[1]

, где
	$args[0]	-	уникальный идентификатор предмета.
	$args[1]	-	управляющая конструкция. Список рабочих управляющих конструкций:
			//nope.goto//	-	запрещает автоматический переход на текущую локацию.

--Подсчёт количества предметов--

Идентичные предметы описываются как один объект с изменением значения kolvo_array. Для уменьшения количества написана процедура minus.obj, которая уничтожает объект, если значение kolvo_array становится равным нулю.

gosub 'minus.obj',$args[0],args[1]

, где
	$args[0]	-	уникальный идентификатор предмета.
	args[1]		-	на сколько уменьшается значение kolvo_array.

--Контекстное меню предметов--

Контекстное меню предметов - это всплывающее меню, которое выводится при щелчке на названии предмета. Каждый пункт этого меню - команда для работы с предметом, которая описывается специальной локацией. Само меню собирается на служебной локации onObjClick.

Вот список локаций, описывающих команды работы с предметами, а так же возможные названия пунктов меню:

	menu.info	-	вывод информации о предмете. "Информация"
	menu.use	-	надевание предмета типа [доспех]. "Надеть"
	menu.useon	-	переход на другую локацию при использовании предмета (возможность использовать предмет определяется по наличию тега [useon:00]). "Воспользоваться"
	menu.put	-	сброс предмета на локации (не работает для предметов, помеченных как квестовые [quest]). "Выбросить"
	menu.eat	-	"съедание" предмета типа [еда], или "выпивание" предмета типа [напиток]. "Съесть", "Сделать глоток"
	menu.sale	-	"продажа" предмета. "Продать"

	menu.dynamic	-	эта локация обрабатывает пункты меню предмета, созданные при помощи динамического кода в $run_array.

Все пункты меню воспроизводятся автоматически в зависимости от описания предмета, содержимого локации, или состояния игровых переменных.

--Типы предметов. Набор признаков--

Все предметы игры относятся к классу <obj>. Над объектами этого класса игрок может проделывать три базовых действия: поднять с локации, сбросить на локацию, просмотреть информацию о предмете.

Помимо этого каждый предмет обладает набором признаков и свойств, которые позволяют проделывать над предметом дополнительные действия. Например, над предметами типа [еда] можно совершить действие: съесть. То есть объект этого типа обладает свойством "съедобный".

Один предмет может обладать различными свойствами, а потому и причисляться может к разным типам. Все типы, к которым причисляется данный предмет, указываются в специальном теге:

	[np: :np]
		-	тег набора признаков. Между двоеточиями перечисляются типы, к которым причисляется данный предмет (набор признаков). Каждый тип указывается в квадаратных скобках.

Вот типы предметов, используемые в игре:

	[снаряжение]
		-	тип некоторых объектов, полученных героем в начале игры, а так же некоторых других объектов.
	[браслет]
		-	объекты этого типа "одеваются на запястье".
	[оружие]
		-	объектами этого типа можно сражаться, вести бой, уничтожать врагов.
	[холодное]
		-	объекты этого подтипа являются оружием ближнего боя
	[меч]
		-	объекты этого подтипа являются колюще-режущим оружием
	[огнестрельное]
		-	объекты этого подтипа являются оружием дальнего боя
	[пистолет]
		-	объекты этого подтипа являются оружием малого калибра
	[доспех]
		-	над объектами этого типа можно совершать действие "надеть"
	[очки]
		-	объекты данного подтипа "надеваются на лицо"
	[инфракрасное зрение]
		-	объекты данного подтипа позволяют "видеть в темноте"
	[еда]
		-	объекты данного типа можно "употреблять в пищу"
	[лекарство]
		-	объекты данного типа используются для "залечивания ран"
	[снаряд]
		-	объекты данного типа расходуются при использовании.
	[пояс]
		-	объекты данного типа можно "надеть на пояс"
	[заряженный]
		-	заряд объектов данного типа расходуется при использовании.
	[монета]
		-	объекты данного типа "попадают в карман".
	[фляга]
		-	объекты данного типа могут быть родительскими для объектов типа [наполнитель]
	[напиток]
		-	объекты данного типа могут быть "выпить".
	[жидкость]
		-	объекты, обладающие свойством "жидкий"
	[наполнитель]
		-	объекты, которыми можно "наполнять" другие объекты
	[верёвка]
		-	объекты обладающие четырьмя свойствами: длинный, тонкий, прочный, эластичный
	[кольцо]
		-	объекты этого типа можно "надевать на пальцы"
	[шлем]
		-	объекты этого типа можно "надевать на голову"
	[неизвестное]
		-	объект, внятное назначение которого отсутствует
	[плащ]
		-	объект, который можно "надеть на плечи"
	[амулет]
		-	объект, который можно "надеть на шею"

Некоторые свойства предметов определяются не по типу, а по сверхтипу, который либо не указывается явно, либо указывается, но вне набора признаков.
	
	[useon:00]
		-	предметы, тела которых содержат этот тег, относятся к сверхтипу тактических предметов. Т.е. это предметы, которые можно использовать только в определённых ситуациях.
	[quest]
		-	предметы, тела которых содержат этот тег, относятся к сверхтипу квестовых предметов. Т.е. предметов, необходимых для прохождения игры. Над такими предметами уже нельзя произвести действие "сбросить на локацию".

Некоторым предметам передаются индивидуальные свойства, которые не влияют на общую механику игры, но отличают некоторым образом эти предметы от других предметов того же вида. Например, в игре "Вереница миров" есть предмет "Верёвка". Этот предмет можно получить в разных местах и всякий раз свойства этого предмета и механика использования одинаковы. Единственное различие "Верёвок" из разных мест состоит в выводимом описании. Индивидуальные свойства отмечаются индивидуальными тегами вне набора признаков. Индивидуальные типы не воспринимаются и не обрабатываются механизмами движка как таковыми.

Механизмы движка обрабатывают все известные типы автоматически. Т.е. достаточно указать предмету тип [еда] и предмет будет обрабатываться как еда, т.е. игрок получит в распоряжение действие "съесть".

--Взаимодействие игрока с предметами. onObjClick--

